<template>
  <el-dialog
    v-model="dialog.visible"
    :title="dialogTitle"
    @open="openHandler"
    @close="closeHandler"
    :close-on-click-modal="false"
    append-to-body
    center
  >
    <el-form
      ref="dataForm"
      :rules="formRules"
      :model="entity"
      :disabled="operation == 3"
      label-suffix="："
    >
      <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item prop="roleName" label="角色名称">
            <el-input
              v-model="entity.roleName"
              placeholder="请输入角色名称"
              clearable
              :disabled="entity.roleBuiltIn"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item prop="roleEnable" label="角色是否启用">
            <el-switch
              v-model="entity.roleEnable"
              :disabled="entity.roleBuiltIn"
            />
          </el-form-item>
        </el-col>
      </el-row>

      <el-tabs v-model="client.clientId" @tab-click="clientTabClickHandler">
        <el-tab-pane
          v-for="i in clients"
          :key="i.id"
          :label="i.clientName"
          :name="i.clientId"
        >
        </el-tab-pane>
      </el-tabs>

      <el-form-item prop="menuIds" label="权限">
        <el-table :data="client.menus" row-key="id" border default-expand-all>
          <el-table-column label="名称">
            <template #default="scope">
              {{ scope.row.menuName }}
            </template>
          </el-table-column>
          <el-table-column prop="menuPermission" label="权限" />

          <el-table-column prop="menuType" label="菜单类型" width="100">
            <template #default="scope">
              <dictionary-label :value="scope.row.menuType" dicKey="menuType" />
            </template>
          </el-table-column>

          <el-table-column label="授权" width="100">
            <template #default="scope">
              <el-switch
                v-if="scope.row.menuName"
                v-model="scope.row.checked"
                :disabled="scope.row.disabled"
                @change="permissionChangeHandler(scope.row)"
              />
            </template>
          </el-table-column>
          <el-table-column label="设为首页" width="100">
            <template #default="scope">
              <el-switch
                v-if="scope.row.menuType == 'MENU'"
                v-model="scope.row.index"
                :disabled="!scope.row.checked"
                @change="indexChangeHandler(scope.row)"
              />
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
    </el-form>

    <template #footer>
      <cancel-button @click="dialog.visible = false" />
      <save-button
        v-if="operation != 3"
        :loading="loading"
        @click="saveHandler"
      />
    </template>
  </el-dialog>
</template>
<script>
import { officialClients, getDetail, save, update } from '@/api/upms/role'
import { fetchTree } from '@/api/upms/menu'

export default {
  name: 'RoleEdit',
  props: {
    dialog: {
      type: Object,
      required: true,
    },
  },
  emits: ['success'],
  data() {
    return {
      loading: false,
      entity: {},
      formRules: {
        roleName: [
          { required: true, message: '请输入角色名称', trigger: 'blur' },
        ],
      },
      titleMap: {
        1: '新建角色',
        2: '编辑角色',
        3: '查看角色',
      },
      clients: [],
      client: {},
    }
  },
  computed: {
    operation() {
      return this.dialog.operation
    },
    dialogTitle() {
      return this.titleMap[this.dialog.operation]
    },
  },
  methods: {
    async openHandler() {
      let res = await officialClients()
      let clients = res.data.data

      this.clients = [{ clientId: '0', clientName: window.clientName }]
      for (let clientId in clients) {
        let clientName = clients[clientId]
        this.clients.push({ clientId: clientId, clientName: clientName })
      }

      this.client = this.clients[0]

      if (this.operation == 1) {
        this.entity = { roleEnable: true }
      } else {
        let res = await getDetail(this.dialog.entity.id)
        this.entity = res.data.data
      }

      this.fetchMenuTree()
    },
    closeHandler() {
      this.entity = {}
      this.$refs.dataForm.clearValidate()
    },
    fetchMenuTree() {
      let findGranted = (clientId, menuId) => {
        for (let i in this.entity.roleMenus) {
          let roleMenu = this.entity.roleMenus[i]
          if (roleMenu.clientId == clientId && roleMenu.menuId == menuId) {
            return roleMenu
          }
        }
        return null
      }

      fetchTree().then((res) => {
        let result = JSON.stringify(res.data.data)

        for (let i in this.clients) {
          let client = this.clients[i]
          let menus = JSON.parse(result)

          for (let j in menus) {
            let menu = menus[j]
            let roleMenu = findGranted(client.clientId, menu.id)
            if (roleMenu) {
              menu.checked = true
              menu.disabled = roleMenu.builtIn
              menu.index = roleMenu.index
            } else {
              menu.checked = false
              menu.index = false
            }

            for (let k in menu.children) {
              let child = menu.children[k]
              roleMenu = findGranted(client.clientId, child.id)
              if (roleMenu) {
                child.checked = true
                child.disabled = roleMenu.builtIn
                child.index = roleMenu.index
              } else {
                child.checked = false
                child.index = false
              }

              for (let l in child.children) {
                let permission = child.children[l]
                roleMenu = findGranted(client.clientId, permission.id)
                if (roleMenu) {
                  permission.checked = true
                  permission.disabled = roleMenu.builtIn
                  permission.index = roleMenu.index
                } else {
                  permission.checked = false
                  permission.index = false
                }
              }
            }
          }

          client.menus = menus
        }
      })
    },

    saveHandler() {
      this.$refs.dataForm.validate((valid) => {
        if (valid) {
          this.loading = true

          let data = {
            id: this.entity.id,
            roleName: this.entity.roleName,
            roleEnable: this.entity.roleEnable,
            clientRoleMenus: [],
          }

          for (let i in this.clients) {
            let client = this.clients[i]
            let clientRoleMenu = {
              clientId: client.clientId,
              indexMenuId: null,
              menuIds: [],
            }
            data.clientRoleMenus.push(clientRoleMenu)

            for (let j in client.menus) {
              let menu = client.menus[j]
              if (menu.checked) {
                clientRoleMenu.menuIds.push(menu.id)
                if (menu.index) {
                  clientRoleMenu.indexMenuId = menu.id
                }
              }

              for (let k in menu.children) {
                let child = menu.children[k]
                if (child.checked) {
                  clientRoleMenu.menuIds.push(child.id)
                  if (child.index) {
                    clientRoleMenu.indexMenuId = child.id
                  }
                }

                for (let l in child.children) {
                  let permission = child.children[l]
                  if (permission.checked) {
                    clientRoleMenu.menuIds.push(permission.id)
                  }
                }
              }
            }
          }

          let edit = this.operation == 1 ? save : update
          edit(data)
            .then(() => {
              this.dialog.visible = false
              this.$message.success('保存成功')
              this.$emit('success')
            })
            .finally(() => {
              this.loading = false
            })
        }
      })
    },

    clientTabClickHandler(pane) {
      for (let i in this.clients) {
        let client = this.clients[i]

        if (pane.paneName == client.clientId) {
          this.client = client
          break
        }
      }
    },
    permissionChangeHandler(row) {
      if (!row.checked) {
        row.index = false
      }

      for (let i in row.children) {
        let child = row.children[i]
        child.checked = row.checked

        for (let j in child.children) {
          child.children[j].checked = row.checked
        }
      }
    },
    indexChangeHandler(row) {
      if (!row.index) {
        return
      }

      for (let i in this.client.menus) {
        let menu = this.client.menus[i]
        if (menu.id == row.id) continue

        if (menu.menuType == 'MENU') {
          menu.index = false
        } else if (menu.menuType == 'CATALOG') {
          for (let k in menu.children) {
            let child = menu.children[k]
            if (child.id == row.id) continue

            if (child.menuType == 'MENU') {
              child.index = false
            }
          }
        }
      }
    },
  },
}
</script>
